﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using MMOShared;
using System.IO;

namespace MMOMasterServer
{
    public class MasterServerDB
    {
        private MySqlConnection _connection;
        private MySqlCommand _command;
        private MySqlDataReader _reader;
        private static readonly object _locker = new object();

        private string _server, _database, _user;
        public MasterServerDB(string server, string database, string user, string pass)
        {
            lock (_locker)
            {
                string connectionString = "SERVER=" + server +
                    ";DATABASE=" + database +
                    ";UID=" + user +
                    ";PASSWORD=" + pass + ";";

                _server = server;
                _database = database;
                _user = user;

                _connection = new MySqlConnection(connectionString);
                _command = _connection.CreateCommand();
                _connection.Open();
            }
        }

        ~MasterServerDB()
        {
            lock (_locker)
            {
                _connection.Close();
            }
        }

        public ServerList getServers()
        {
            List<ServerEntry> servers = new List<ServerEntry>();
            lock (_locker)
            {
                _command.CommandText = "select * from `servers`";
                _reader = _command.ExecuteReader();
                int i = 0;
                while (_reader.Read())
                {
                    string name = _reader.GetString(1);
                    string address = _reader.GetString(2);
                    bool avail = _reader.GetBoolean(3);
                    int port = _reader.GetInt32(4);
                    ServerEntry e = new ServerEntry(name,address,avail,port);

                    servers.Add(e);
                    i++;
                }
                _reader.Close();
            }
            return new ServerList(servers.ToArray());
        }

        public void GetUpdateInfo(UInt16 version, out long size, out int numFiles, out int numPieces)
        {
            size = 0;
            numFiles = 0;
            numPieces = 0;
            lock (_locker)
            {
                string sqlQuery = "SELECT `update_size`,`update_piece_count`,`update_file_count` FROM `mmo_test_game`.`updates` WHERE `update_version` = '" + version + "' LIMIT 1;";
                _command.CommandText = sqlQuery;
                _reader = _command.ExecuteReader();
                while (_reader.Read())
                {
                    size = _reader.GetInt64(0);
                    numPieces = _reader.GetInt32(1);
                    numFiles = _reader.GetInt32(2);
                    break;
                }
                _reader.Close();
            }
        }

        public List<FileUpdatePiece> RequestUpdateFileList(UInt16 version)
        {
            lock (_locker)
            {
                List<FileUpdatePiece> updates = new List<FileUpdatePiece>();

                string sqlQuery = "SELECT * FROM `" + _database + "`.`update_" + version.ToString() + "`";

                _command.CommandText = sqlQuery;

                _reader = _command.ExecuteReader();
                while (_reader.Read())
                {
                    string resID = _reader.GetString(1);
                    long startByte = _reader.GetInt64(2);
                    long size = _reader.GetInt64(3);
                    bool isDelete = _reader.GetBoolean(4);
                    byte[] data = new byte[size];
                    _reader.GetBytes(5, 0, data, 0, (int)size);

                    FileUpdatePiece p = new FileUpdatePiece(resID, startByte, size, isDelete);
                    p.Data = data;

                    updates.Add(p);
                }
                _reader.Close();
                return updates;
            }
        }

        public bool loginAccount(string user, string password)
        {
            lock (_locker)
            {
                _command.CommandText = "select * from `users` where `user_name`=\"" + user + "\" and `user_password`=\"" + password + "\"";
                _reader = _command.ExecuteReader();
                if (_reader.HasRows)
                {
                    _reader.Close();
                    return true;
                }
            }
            _reader.Close();
            return false;
        }

        public void setLoggedIn(string user)
        {
        }
    }
}
